package org.ne.springboot.utils.PaperHandleUtils.AbstractTranslateCheckUtils;

import jakarta.servlet.http.HttpServletResponse;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.json.JSONArray;
import org.json.JSONObject;
import org.ne.springboot.utils.PaperHandleUtils.PaperContentCheckUtils.SparkClient;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;


public class TranslateCheckUtils {
        
    //divide_docx_by_heading_1
    public static List<Integer> divideDocxByHeading1(XWPFDocument docx) {
        List<Integer> headList = new ArrayList<>();

        for (int i = 0; i < docx.getParagraphs().size(); i++) {
            if (headList.size() == 2) {
                break;
            }

            XWPFParagraph paragraph = docx.getParagraphs().get(i);
            String text = paragraph.getText().replace("\n", "").replace("\t", "").replace(" ", "");

            if (text.equals("摘要") || text.equals("Abstract")) {
                headList.add(i);
            }
        }
        return headList;
    }

    //get_text_from_abstract_2_key
    public static Object[] getTextFromAbstractToKey(int index, XWPFDocument docx) {
        StringBuilder text = new StringBuilder();
        boolean found = false;
        List<XWPFParagraph> paragraphs = docx.getParagraphs();
        for (int i = index; i < paragraphs.size(); i++) {
            XWPFParagraph paragraph = paragraphs.get(i);
            text.append(paragraph.getText()).append("\n");

            List<XWPFRun> runs = paragraph.getRuns();
            if (!runs.isEmpty() &&
                    (paragraph.getText().startsWith("Key") || paragraph.getText().startsWith("关键词：")) &&
                    runs.get(0).isBold() &&
                    (i > 0 && paragraphs.get(i - 1).getRuns().isEmpty())) {
                found = true;
                break;
            }
        }
        return new Object[]{text.toString(), found};
    }

    //def output(text, out_path)
    public static XWPFDocument output(String text) throws IOException {
        // Create a new Word document
        XWPFDocument out = new XWPFDocument();

        // Add main heading "摘要翻译检测报告"
        XWPFParagraph heading = out.createParagraph();
        XWPFRun headingRun = heading.createRun();
        headingRun.setText("摘要翻译检测报告");
        headingRun.setBold(true);
        headingRun.setFontSize(20);
        // Approximate equivalent to Heading 0 in python-docx

        int star = 0;
        for (int i = 0; i < text.length(); i++) {
            if (text.charAt(i) == '[') {
                star = i;
                break;
            }
        }
        int end = text.length();
        for (int i = text.length() - 1; i >= 0; i--) {
            if (text.charAt(i) == ']') {
                end = i;
                break;
            }
        }
        String jsonText = (end >= star && end < text.length()) ? text.substring(star, end + 1) : text;

        Object jsonData;
        try {
            jsonData = new JSONObject(jsonText); // 尝试解析为对象
            // 如果是对象，直接放入 JSONArray
            jsonData = new JSONArray().put(jsonData); // 将整个对象放入数组
        } catch (Exception e) {
            try {
                jsonData = new JSONArray(jsonText); // 回退到数组解析
            } catch (Exception e2) {
                throw new RuntimeException("无法解析 JSON: " + e2.getMessage(), e2);
            }
        }

        // Parse JSON data
        JSONArray arrayData = (jsonData instanceof JSONArray) ? (JSONArray) jsonData : new JSONArray().put(jsonData);

        // Iterate through JSON data and add content to document
        int cnt = 0;
        for (int i = 0; i < arrayData.length(); i++) {
            JSONObject item = arrayData.getJSONObject(i);

            // Add subheading "第X处"
            XWPFParagraph subHeading = out.createParagraph();
            XWPFRun subHeadingRun = subHeading.createRun();
            subHeadingRun.setText("第" + (cnt + 1) + "处");
            subHeadingRun.setBold(true);
            subHeadingRun.setFontSize(16); // Approximate equivalent to Heading 1 in python-docx
            cnt++;

            // Add paragraphs for Chinese text, English text, error message, and suggestion
            XWPFParagraph chinesePara = out.createParagraph();
            chinesePara.createRun().setText("中文原文：" + item.getString("chinese_text"));

            XWPFParagraph englishPara = out.createParagraph();
            englishPara.createRun().setText("英文原文：" + item.getString("english_text"));

            XWPFParagraph errorPara = out.createParagraph();
            errorPara.createRun().setText("错误原因：" + item.getString("msg"));

            XWPFParagraph suggestionPara = out.createParagraph();
            suggestionPara.createRun().setText("建议改正：" + item.getString("ans"));
        }
        return out;

    }

    //def abstract_translate_check_begin(path, out_path):
    private static final Map<String, String> exceptions = new HashMap<>() {{
        put("AbstractNotFound", "未找齐摘要以及对应翻译，请检查格式及内容是否正确");
        put("returnMsgNotFormated", "返回值未严格符合格式要求，请重试");
    }};

    public static XWPFDocument check(HttpServletResponse httpServletResponse, MultipartFile file, String model) throws IOException {

        XWPFDocument doc = null;
        try (InputStream is = file.getInputStream()) {
            doc = new XWPFDocument(is);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // Extract abstract indices
        List<Integer> indices = TranslateCheckUtils.divideDocxByHeading1(doc);

        if (indices.size() < 2) {
            XWPFDocument out = new XWPFDocument();
            XWPFParagraph para = out.createParagraph();
            para.createRun().setText(exceptions.get("AbstractNotFound"));
            doc.close();
            return out;
        }

        XWPFDocument out = new XWPFDocument();
        // Extract abstract texts
        Object[] result1 = TranslateCheckUtils.getTextFromAbstractToKey(indices.get(0), doc);
        Object[] result2 = TranslateCheckUtils.getTextFromAbstractToKey(indices.get(1), doc);
        String text1 = (String) result1[0];
        boolean flag1 = (boolean) result1[1];
        String text2 = (String) result2[0];
        boolean flag2 = (boolean) result2[1];

        if (flag1 && flag2) {
            // Prompt for AI
            String prompt = "作为专业的论文审批教授，针对每句中文判断中文摘要的英文翻译是否准确，以严格JSON格式返回，除json内容外无其他内容，并且json内容外无标点，无数字，无字符，其中包含字段chinese_text为翻译不正确的中文原文内容,english_text为chinese_text对应的英文原文，msg字段用来表示翻译不正确的原因，ans字段表示纠正后的英文翻译\n";

//            String text = "中文："+text1+" 英文："+text2;
            String text = text1+text2;

            System.out.println(text);



            SparkClient sparkClient = new SparkClient();
            sparkClient.setModel(model);

            HashMap<String, Object> format = new HashMap<>();
            format.put("chinese_text","翻译不正确的中文原文内容");
            format.put("english_text","The incorrect English translation of the Chinese text.");
            format.put("msg","翻译不准确的原因说明");
            format.put("ans","The corrected English translation.");
            sparkClient.setFormat(format);

            Map<String, Object> result = sparkClient.processRequest(prompt, text);

            String aiResponse;
            if ("success".equals(result.get("status"))) {

                Map<String, Object> answer = (Map<String, Object>) result.get("answer");
                // 假设 answer 包含 JSON 数据，转换为字符串
                aiResponse = new JSONObject(answer).toString();

            } else {
                throw new IOException("AI 处理失败: " + result.get("message"));
            }

            System.out.println(aiResponse);
            out = output(aiResponse);
        } else {
            XWPFParagraph para = out.createParagraph();
            para.createRun().setText(exceptions.get("AbstractNotFound"));
        }
        doc.close();
        return out;

    }

    public static XWPFDocument translate(HttpServletResponse httpServletResponse, MultipartFile file, String model) throws IOException {
        if (file == null || file.isEmpty()) {
            throw new IllegalArgumentException("文件不能为空");
        }
        return check(httpServletResponse, file, model);
    }

}
